package evacuator;

import jade.core.AID;
import jade.core.Agent;
import jade.domain.DFService;
import jade.domain.FIPAException;
import jade.domain.FIPAAgentManagement.DFAgentDescription;
import jade.domain.FIPAAgentManagement.FailureException;
import jade.domain.FIPAAgentManagement.NotUnderstoodException;
import jade.domain.FIPAAgentManagement.RefuseException;
import jade.domain.FIPAAgentManagement.ServiceDescription;
import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;
import jade.lang.acl.UnreadableException;
import jade.proto.AchieveREResponder;

import java.util.ArrayList;
import java.util.List;

import moves.Movement.Direction;
import moves.MovementSender;
import path.DistanceList;
import path.Path;
import path.PathTest;
import agents.UtilsAgents;
import building.Cell;
import building.InfoAgent;
import building.InfoAgent.Age;
import building.InfoAgent.Gender;
import building.InfoGame;
import civilian.SendFinishDownload;
import civilian.SendFinishLoad;

public class EvacuatorAgent extends Agent {

	/**
	 * 
	 * 
	 * @author Carolina Arce
	 */
	private static final long serialVersionUID = 1L;
	private evacuator.ProtocolContractNetInitiator contractNetInitiator;
	private ArrayList<AID> civilians;
	private InfoGame game;
	private int currFloor = -1;
	private int countCivilians = 0;
	private int countInjured = 0;
	private int countPanic = 0;
	private int countDied = 0;
	private int countBlocked = 0;
	private ReceiveFinishLoad receiveFinishLoad;
	private SendFinishLoad sendFinishLoad;
	private SendFinishDownload finishDownload;
	private Cell content;
	Direction step = null;
	private MovementSender ms;
	private Path short_path;
	private int my_x, my_y;
	private int my_f;
	private boolean freeAgent = true;// true = free false= transport
	private boolean accepted;
	InfoAgent infoAgent;
	List<Cell> injured;
private boolean subGoalReach=false;
	private int mob_r;
	private Age age;
	private Gender gender;
	private float healthy;

	private int panic_stiken;
	private boolean p_injured;
	private boolean died, out;
	public List<Cell> panicCivilian;


	protected void setup() {
		System.out.println(this.getLocalName() + " is ready.");

		// Register the agent to the DF
		ServiceDescription sd1 = new ServiceDescription();
		sd1.setType(UtilsAgents.EVACUATOR_AGENT);
		sd1.setName(getLocalName());
		sd1.setOwnership(UtilsAgents.OWNER);
		DFAgentDescription dfd = new DFAgentDescription();
		dfd.addServices(sd1);
		dfd.setName(getAID());
		try {
			DFService.register(this, dfd);
			// showMessage("Registered to the DF");
			System.out.println("Registered to the DF");
		} catch (FIPAException e) {
			System.err.println(getLocalName() + " registration with DF "
					+ "unsucceeded. Reason: " + e.getMessage());
			doDelete();
		}

		// Add a Behavior to receive Turns
		MessageTemplate mt = MessageTemplate
				.MatchProtocol(agents.UtilsAgents.PROTOCOL_TURN);
		this.addBehaviour(new QueriesReceiver(this, mt));

		MessageTemplate msInf = MessageTemplate
				.MatchProtocol(agents.UtilsAgents.INFORM);
		this.addBehaviour(new HelpResponder(this, msInf));

		receiveFinishLoad = new ReceiveFinishLoad();
		sendFinishLoad = new SendFinishLoad();
		contractNetInitiator = new ProtocolContractNetInitiator();
		finishDownload = new SendFinishDownload();
		ms = new MovementSender(this, this.getAID(),
				agents.UtilsAgents.COORDINATOR_AGENT);

		/**
		 * Add a behavior to receive that the harvester load successful garbage.
		 */
		receiveFinishLoad.addBehaviour(this);

		/**
		 * Add a behavior to receive that the harvester download all garbage
		 * into recycling center.
		 */
		new ReceiveFinishLoad().addBehaviour(this);

		/**
		 * Add a behavior to receive that the harvester download all garbage
		 * into recycling center.
		 */
		new ReceiveFinishDownload().addBehaviour(this);
		/**
		 * Add a behavior to relay movement orders from harvesters to the
		 * coordinator agent.
		 */
		new MovementRely().addBehavior(this,
				agents.UtilsAgents.COORDINATOR_AGENT);
		// super.setup();
		panicCivilian = new ArrayList<Cell>();
		super.setup();
	}

	public String toString() {

		return "Evacuator [aid=" + this.getAID() + ", healty=" + healthy
				+ ", male=" + this.gender.toString() + ", age="
				+ this.age.toString() + "]";
	}

	public boolean updateEv_byInf(InfoAgent inf) {
		if (inf.getAID().equals(this.getAID())) {
			this.mob_r = inf.reduceMob;

			this.age = inf.getAge();

			this.gender = inf.getGender();
			healthy = inf.getHealty();

			this.panic_stiken = inf.getPanic();
			this.p_injured = inf.p_injured;
			died = inf.died;
			out = inf.out;
			return true;
		}
		return false;
	}

	class QueriesReceiver extends AchieveREResponder {

		private InfoGame game;
		private Cell cell;
		private AID agentInPanic;

		@Override
		protected ACLMessage prepareResponse(ACLMessage arg0)
				throws NotUnderstoodException, RefuseException {
			return null;
		}

		@Override
		protected ACLMessage prepareResultNotification(ACLMessage arg0,
				ACLMessage arg1) throws FailureException {
			return null;
		}

		protected ACLMessage handleRequest(ACLMessage arg0)
				throws NotUnderstoodException, RefuseException {
			try {
				Object objectReceived = arg0.getContentObject();


				if (objectReceived instanceof InfoGame) {
					// Is the coordinator informing of a new turn
					game = (InfoGame) objectReceived;
					Cell temp = UtilsAgents.findAgent(myAgent.getAID(),
							game);
					System.out.println(this.myAgent.getLocalName() + " temp "
							+ temp);
					if (UtilsAgents.checkStairs(game) != null) {
						System.err.println("Agent in the stairs "
								+ UtilsAgents.checkStairs(game).getLocalName());
					}
					if (temp != null) {
						InfoAgent oldInfoAgent = temp.getAgent();
						currFloor = temp.getFloor();
						updateEv_byInf(oldInfoAgent);
						panicCivilian = game.getPanicCivilianByFloor(temp);
					}
					System.out.println();
					if (temp == null
							&& game.isAgentRemoved(this.myAgent.getAID())
							&& agents.UtilsAgents.getEvacuatorsByFloor(game, 0)
									.size() == 0) {
						currFloor = 0;
						System.out.println("agents is out"
								+ this.myAgent.getLocalName());
					}

					showMessage("Evacuator: New turn received from coordinator: "
							+ this.myAgent.getLocalName()
							+ game.getInfo().getTurn());

					countCivilians = 0;
					countInjured = 0;
					countPanic = 0;
					countDied = 0;
					countBlocked = 0;

					// try{
					// if (temp != (null)) {

					// Find all my agents and send them the new turn
					ACLMessage message = new ACLMessage(ACLMessage.REQUEST);

					for (int r = 0; r < game.getMap().length; r++)
						for (int c = 0; c < game.getMap().width; c++) {
							Cell cell = game.getCell(r, c, currFloor);
							if (cell != null)
								if (cell.isThereAnAgent()) {
									InfoAgent a = cell.getAgent();
									if (a.getAgent().equals("C")) {
										message.addReceiver(a.getAID());
										countCivilians++;

										System.out.println(this.myAgent
												.getLocalName()
												+ "sending initial request"
												+ a.getAID());

										if (a.isInjured())
											countInjured++;
										if (a.getPanic() >= 80)
											countPanic++;
										if (a.died == true)
											countDied++;
										if (a.imBlocked(a.getAID(), game) == true)
											countBlocked++;
									}
								}
						}// for



					countCivilians = countCivilians - countInjured - countPanic
							- countDied - countBlocked;
					System.out.println(this.myAgent.getLocalName()
							+ "countCivilians" + countCivilians + "countPanic"
							+ countPanic + "died" + countDied + "countInjured"
							+ countInjured + "countBlocked" + countBlocked);

					if (countPanic == 0 && countCivilians != 0 && temp != null) {

                                                 System.out.println("no more civilians in my floor"
								+ myAgent.getLocalName() + content);
						// if()
						setInfoGame(game);
						// Actualizing game.
						// receiveFinishLoad.setGame(game);
					}
					if (countCivilians == 0 && countPanic == 0 && temp != null) {

                                                 System.out.println("no more civilians in my floor"
								+ myAgent.getLocalName() + content);
						subGoalReach = true;
						setInfoGame(game);
						// Actualizing game.
						// receiveFinishLoad.setGame(game);
					}

					else {
						if (countPanic != 0) {

							Cell panicC = panicCivilian.get(0);
							agentInPanic = helpCivilians(game, panicC);
							if (agentInPanic != null) {
								game.getPanicCivilianByFloor(temp).remove(0);
								panicC.getAgent().panic = 0;
							}
						}

						// if(currFloor == temp.getAgent().getMyFloor() ||
						// agents.UtilsAgents.getEvacuatorsByFloor(game,
						// currFloor).size()==1){
						System.out.println(this.myAgent.getAID()
								+ "Civilians in my floor" + countCivilians);
						message.setProtocol(agents.UtilsAgents.PROTOCOL_TURN);
						message.setSender(this.myAgent.getAID());
						message.setContentObject(game);

						// Actualizing game.
						receiveFinishLoad.setGame(game);

						// Send new torn for all civilian.
						this.myAgent.send(message);
					
						for (int r = 0; r < game.getMap().length; r++) {
							for (int c = 0; c < game.getMap().width; c++) {

								Cell cell = game.getCell(r, c, currFloor);
								if (cell != null) {
									// If that cell is building.
									if (cell.getCellType() == Cell.DOOR) {
										content = cell;
										System.out
												.println("ho trovato una porta"
														+ content);
										if (temp != null) {
											Cell varAgent = agents.UtilsAgents
													.findAgent(this.myAgent
															.getAID(), game);
											int dist = agents.UtilsAgents
													.cellDistance(varAgent,
															content);
											/*
											 * if(dist==100000){ //caterina a
											 * volte quando abbiamo la
											 * excepzione si stampa questo Cell
											 * newcontent = agents
											 * .UtilsAgents.getFreePositonsDoor
											 * (content, game).get(0); content =
											 * newcontent; System.out
											 * .println("change content!!!"); }
											 */
											System.out.println("distance"
													+ dist
													+ "evacuator"
													+ this.myAgent
															.getLocalName()
													+ " " + content);
										}
										contractNetInitiator.addBehaviour(
												this.myAgent, content, game);
									}
								}
							}
						}
					}

				}// if

				// }// if

			} catch (UnreadableException e) {
				e.printStackTrace();
				showMessage("Received an Object that cannot be understood");
			} catch (Exception e) {
				e.printStackTrace();
			}

			return super.handleRequest(arg0);

		}

		private void showMessage(String string) {
			// TODO Auto-generated method stub
			System.out.println(string);
		}

		/**
          *
          */
		private static final long serialVersionUID = -6176920249600913698L;

		public QueriesReceiver(Agent arg0, MessageTemplate arg1) {
			super(arg0, arg1);
		}
	}
	/***** CODE CATERINA ******************************/

	public AID helpCivilians(InfoGame infoGame, Cell panicC) {
		System.err.println("Help civilians ");
		this.game = infoGame;
		accepted = false;
		int distance = -1;
		Cell myContent = panicC;
		try {
			infoAgent = agents.UtilsAgents.findAgent(this.getAID(), infoGame)
					.getAgent();
			Cell varAgent = agents.UtilsAgents.findAgent(this.getAID(),
					infoGame);
			System.out.println("Agent " + infoAgent.getAID() + "in position"
					+ varAgent);
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			System.out.println("Help civilians init " + e1);
		}
		Cell begin = new Cell(Cell.FREE);

		my_x = agents.UtilsAgents.findAgent(this.getAID(), infoGame)
				.getColumn();
		my_y = agents.UtilsAgents.findAgent(this.getAID(), infoGame).getRow();
		my_f = agents.UtilsAgents.findAgent(this.getAID(), infoGame).getFloor();

		System.out.println("CONTENT" + myContent);
		if (myContent != null) {

			try {

				distance = evaluateAction(myContent);
				System.out.println("Evacuator: current position" + my_f + "x"
						+ my_x + "y" + my_y);
				begin.setColumn(my_x);
				begin.setRow(my_y);
				begin.setFloor(my_f);
				System.out.println("Evacuator:distancia calculada por"
						+ this.getLocalName() + ":" + distance + "in floor"
						+ my_f);
			} catch (Exception e) {

				System.out.println("Evacuator exception helpCivilians "
						+ e.toString());
			}

			// look at the perimeter
			if (distance == 1) {
				System.out.println("Evacuator distancia 1 ");

				System.out.println("Caso 1");
				step = getNextStep();
				InfoAgent ip = panicC.getAgent();
				System.out.println("Evacuator " + this.getLocalName()
						+ ":sono dal ferito " + ip.getAID().getLocalName());

				ip.panic = 0;
				System.out.println("HelpCivilian: "
						+ ip.getAID().getLocalName() + " is not in panic.");
				System.err.println(ip.getAID().getLocalName()
						+ "  set panic=0 -> " + ip.panic);

				ms.put(step);
				freeAgent = true;
				accepted = false;

				// notifyFinishedLoad(this.game);
				return ip.getAID();
			}

			else if (distance == 2) {

				step = getNextStep();
				System.out
						.println("Evacuator:sono a 2 passi dal civile in panico"
								+ this.getLocalName());

				ms.go(step);
				freeAgent = false;
				accepted = true;
				return null;

			}// if

			else if (distance > 2)

			{
				System.out
						.println("Evacuator:sto a più di 2 passo dal civile "
								+ this.getLocalName() + "destination cell R"
								+ myContent.getRow() + " C"
								+ myContent.getColumn());
				distance = evaluateAction(myContent);
				try {
					step = getNextStep();
				} catch (Exception e) {
					System.err
							.println("Evacuator: non ho potuto calcolare il prossimo step ");
				}
				System.out.println("Evacuator:step: " + step);

				ms.go(step);
				freeAgent = false;

			} // else

			else {
				System.out.println("Evacuator null path" + this.getLocalName());
			}

		} else
			System.out.println("Evacuator: content null" + distance);
		return null;

	}

	class HelpResponder extends AchieveREResponder {

		public HelpResponder(Agent a, MessageTemplate mt) {
			super(a, mt);
			// TODO Auto-generated constructor stub
		}

		/**
         *
         */
		private static final long serialVersionUID = 1L;

		@Override
		protected ACLMessage prepareResponse(ACLMessage arg0)
				throws NotUnderstoodException, RefuseException {
			System.out.println("notUnderstood by eva");
			return null;
		}

		@Override
		protected ACLMessage prepareResultNotification(ACLMessage arg0,
				ACLMessage arg1) throws FailureException {
			return null;
		}

		protected ACLMessage handleRequest(ACLMessage arg0)
				throws NotUnderstoodException, RefuseException {
			try {

				String h = arg0.getContent();
				String convId = arg0.getConversationId();
				AID sender = arg0.getSender();
				ACLMessage risp = new ACLMessage(ACLMessage.INFORM);
				if (convId.equals("1")) {
					System.err.println("H " + h);

					risp.setProtocol(UtilsAgents.INFORM);
					risp.setSender(myAgent.getAID());
					risp.setContent("Allarm received");
					risp.addReceiver(sender);

					showMessage("Evacuator received civilian's ( "
							+ sender.getLocalName() + ")  sos.");
					this.myAgent.send(risp);
				}

			} catch (Exception e) {
				e.printStackTrace();
			}
			return super.handleRequest(arg0);
		}

		private void showMessage(String string) {
			// TODO Auto-generated method stub
			System.out.println(string);
		}

	}

	public void setInfoGame(InfoGame infoGame) {
		this.game = infoGame;
		accepted = false;
		int distance = -1;
		System.out.println(game.getRemovedAgents());
		if(!game.isAgentRemoved(this.getAID())){

			Cell varAgent = agents.UtilsAgents.findAgent(this.getAID(), infoGame);
			infoAgent = varAgent.getAgent();
			Cell begin = new Cell(Cell.FREE);

			my_x = agents.UtilsAgents.findAgent(this.getAID(), infoGame).getColumn();
			my_y = agents.UtilsAgents.findAgent(this.getAID(), infoGame).getRow();
			my_f = agents.UtilsAgents.findAgent(this.getAID(), infoGame).getFloor();
			
			Cell door = new Cell(Cell.DOOR);
			System.out.println("SetInfoGame" + content + "/n" +my_x + my_y + my_f);
			door = content;
			if (content != null && content.getFloor() != my_f) {
				content=agents.UtilsAgents.getNearDoor(infoGame, varAgent);
				System.out.println("!!new door" + content );
			}
			if (content != null && content.getFloor() == my_f) {
				System.out.println("content not null");
			if (agents.UtilsAgents.imBlocked(infoGame, this)) {
				System.out.println("I am blocked" + this.getAID());

				List<Cell> receivers = UtilsAgents.getNeighboors(this.getAID(),
						infoGame);
				System.out.println("Ev MIS VECINOS" + receivers.size());
				/*
				 * if(receivers.size()>=1){ AID blockingAgent =
				 * receivers.get(0).getAgent().getAID();
				 * System.out.println("im sending an unblock message");
				 * //protocolSendMove.addBehaviour(myAgent, blockingAgent);
				 * 
				 * }
				 */
			}
			try {
				door = infoGame.getCell(content.getRow(), content.getColumn(),
						content.getFloor());
				System.out.println("CONTENT" + content.isThereAnAgent()
						+ "content vs door" + door.isThereAnAgent());
				System.out.println("CONTENT" + content.getAgent()
						+ "content vs door" + door.getAgent());
				System.out.println("CONTENT" + content + "content vs door"
						+ door);
				distance = evaluateAction(door);
				
				if(distance==10000){
					Cell newcontent = agents.UtilsAgents.getFreePositonsDoor(door, game).get(0);
					door = newcontent;
					System.out
							.println("change content!!!");
					}
				System.out.println("current position" + my_f + "x" + my_x + "y"
						+ my_y);
				begin.setColumn(my_x);
				begin.setRow(my_y);
				begin.setFloor(my_f);
				System.out.println("distancia calculada por el evacuator"
						+ this.getLocalName() + ":" + distance + "in floor"
						+ my_f);
			} catch (Exception e) {

				System.out.println("setinfo" + e.toString());
			}

			// look at the perimeter
				if (distance == 0) {

				if (my_f == 0) {
					step = step.OUT;
					System.out.println("estoy a salvo" + this.getLocalName());
					ms.out(step);
					freeAgent = true;
					accepted = true;
					return;
				} else {
					Cell stairs = door;
					stairs.setRow(infoGame.getNrows() - 1);
					stairs.setFloor(content.getFloor() - 1);
					System.out.println("is there an agent in the stairs?"
							+ stairs + " " + stairs.isThereAnAgent());
					if (stairs.isThereAnAgent()) {
						System.out.println("hay un agente en las escaleras"
								+ door + door.getAgent());

					}

					freeAgent = true;
					accepted = true;
					// notifyFinishedLoad(infoGame);
					step = step.UPFLOOR;
					System.out.println("paso al siguiente piano"
							+ this.getLocalName());
					ms.go_floor(step);
						// notifyFinishedLoad(infoGame); non decommentare!!

					return;

				}
			}

				else if (distance == 1) {

				try {
					if (door.isThereAnAgent()) {
						// ms.go(Direction.NOP);
						System.out
								.println("Civilian:hay un agente en la puerta"
										+ door + door.getAgent());
					} else {
						// protocolSendFinishDownload.addBehaviour(myAgent);
						System.out.println(this.getLocalName()
								+ "la puerta es libre");
					
							step = getNextStep();
							ms.go_floor(step);
						
					//	ms.go(getNextStepDesti(door));
						return;

					}
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}// if
				else if (distance == 2) {

				try {
					
						// protocolSendFinishDownload.addBehaviour(myAgent);
						System.out.println(this.getLocalName()
								+ "la puerta es libre");
						if(subGoalReach==true){
							step = getNextStep();
							ms.go_floor(step);
						
						}
						return;

					
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
 else if (distance > 2 && distance != 10000) {
				distance = evaluateAction(door);
				System.out.println("estoy a mas de un paso de la puerta"
						+ this.getLocalName() + "destination cell" + door);
				step = getNextStep();
				System.out.println("step: " + step);
				ms.go(step);
				return;
			} else {
				System.out
						.println("Evacuator: I havent found a path to the exit "
								+ this.getLocalName());
				ms.go(getNextStepDesti(door));
				return;

			} // else

		}
	}

	}

	
	
	private void notifyFinishedLoad(InfoGame infoGame) {
		DistanceList list = new DistanceList();

		Cell currCell = agents.UtilsAgents.findAgent(this.getAID(), infoGame);// my
																				// pos
		System.out.println("notify finish load" + this.getAID() + " in piano"
				+ currCell.getFloor());

		try {
			Cell goDescarga = sendFinishLoad.blockingMessage(this, currCell);
			System.out.println("Arrived at door");// + goDescarga.getRow()+
													// goDescarga.getColumn()
													// +goDescarga.getFloor());
		} catch (Exception e) {
			System.out.println("non ha trovato la porta" + e.toString());

		}

		freeAgent = false;
	}

	/**
	 * 
	 * @param cell
	 * @return the best distance for harvester to go a one cell
	 */
	private int evaluateAction(Cell cell) {

		int xfinal = cell.getColumn();
		int yfinal = cell.getRow();
		int zfinal = cell.getFloor();
		// return the short path
		// Search my position
		my_x = agents.UtilsAgents.findAgent(this.getAID(), game).getColumn();
		my_y = agents.UtilsAgents.findAgent(this.getAID(), game).getRow();
		my_f = agents.UtilsAgents.findAgent(this.getAID(), game).getFloor();

		if (zfinal == my_f) {
			PathTest test = new PathTest(game);

			System.out.println("*****Protocol Evacuator evaluate action"
					+ zfinal);
			System.out.println(this.getAID() + "Im in floor" + my_f
					+ "destination" + zfinal);
			System.out.println("Evacuator inicial agent " + this.getLocalName()
					+ "in pos" + my_x + " -" + my_y + " in floor" + my_f);

			if (my_y == yfinal && xfinal == my_x && zfinal == my_f) {

				return 0;

			}

			// option 1
			test.PosicioInicial(my_x, my_y, 1, my_f);
			// System.out.println("calcolo pos inicial");
			Path stepsPathFinal1 = test.PosicioFinal(xfinal, yfinal, 1, zfinal);
			// System.out.println(" calcolo path " + this.myAgent.getLocalName()
			// + "in pos1"+my_x + " -"+my_y +
			// "length"+stepsPathFinal1.getLength());

			// option 2
			test.PosicioInicial(my_x, my_y, 2, my_f);
			Path stepsPathFinal2 = test.PosicioFinal(xfinal, yfinal, 2, zfinal);

			// System.out.println("agent " + this.myAgent.getLocalName() +
			// "in pos2"+my_x + " -"+my_y);

			int distFinal = 10000;
			// Control if possible the second option
			if (stepsPathFinal2 != null) {
				distFinal = test.distanciaPesos(stepsPathFinal2);
				short_path = stepsPathFinal2;
				// stepsPathFinal2.printPath();

				// Control if possible the first option
				if (stepsPathFinal1 != null) {

					int distPesosOp1 = test.distanciaPesos(stepsPathFinal1);
					if (distFinal > distPesosOp1) {
						distFinal = distPesosOp1;
						short_path = stepsPathFinal1;
						// stepsPathFinal1.printPath();
					}
				}

			}
			return distFinal;
		} else
			return -1;
	}

	/**
	 * 
	 * @param dest
	 * @return the next Direction where harvester have go
	 */
	private Direction getNextStepDesti(Cell dest) {
		int destination_x = dest.getColumn();
		int destination_y = dest.getRow();

		if (my_x < destination_x && my_y == destination_y) {
			return Direction.RIGHT;

		}
		if (my_x > destination_x && my_y == destination_y) {
			return Direction.LEFT;
		}
		if (my_y < destination_y && my_x == destination_x) {
			return Direction.DOWN;
		}
		if (my_y > destination_y && my_x == destination_x) {
			return Direction.UP;
		}
		if (my_y > destination_y && my_x > destination_x) {
			return Direction.UPLEFT;
		}
		if (my_y < destination_y && my_x < destination_x) {
			return Direction.DOWNRIGHT;
		}

		if (my_x < destination_x && my_y > destination_y) {
			return Direction.UPRIGHT;
		}
		if (my_x > destination_x && my_y < destination_y) {
			return Direction.DOWNLEFT;
		}

		return Direction.NOP;

	}

	/**
	 * 
	 * @return the next Direction where civilian have go, this Direction is
	 *         calculated in short Path
	 */
	private Direction getNextStep() {
		int destination_x = short_path.getX(1);
		int destination_y = short_path.getY(1);

		if (my_x < destination_x && my_y == destination_y) {
			return Direction.RIGHT;

		}
		if (my_x > destination_x && my_y == destination_y) {
			return Direction.LEFT;
		}
		if (my_y < destination_y && my_x == destination_x) {
			return Direction.DOWN;
		}
		if (my_y > destination_y && my_x == destination_x) {
			return Direction.UP;
		}
		if (my_y > destination_y && my_x > destination_x) {
			return Direction.UPLEFT;
		}
		if (my_y < destination_y && my_x < destination_x) {
			return Direction.DOWNRIGHT;
		}

		if (my_x < destination_x && my_y > destination_y) {
			return Direction.UPRIGHT;
		}
		if (my_x > destination_x && my_y < destination_y) {
			return Direction.DOWNLEFT;
		}

		return Direction.NOP;

	}

}